<template>
  <div class="space-y-6">
    <!-- 上传区域（参考 tailwindui Dropzone 风格） -->
    <div
      class="relative block w-full rounded-lg border-2 border-dashed border-gray-300 p-6 text-center hover:border-gray-400 focus:outline-none focus:ring-2 focus:ring-gray-900 focus:ring-offset-2"
      :class="{ 'ring-2 ring-gray-900 ring-offset-1': dragging }"
      @dragover.prevent="dragging = true"
      @dragleave.prevent="dragging = false"
      @drop.prevent="onDrop"
    >
      <svg class="mx-auto h-10 w-10 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 15a4 4 0 004 4h10a4 4 0 004-4m-4-8l-4-4m0 0L9 7m4-4v12" />
      </svg>
      <div class="mt-3 flex text-sm text-gray-600 justify-center">
        <label
          for="file-upload"
          class="relative cursor-pointer rounded-md bg-white font-medium text-gray-900 focus-within:outline-none focus-within:ring-2 focus-within:ring-gray-900 focus-within:ring-offset-2 hover:text-gray-800"
        >
          <span>点击上传</span>
          <input id="file-upload" name="file-upload" type="file" class="sr-only" accept="image/*" :multiple="multiple" @change="onUpload" />
        </label>
        <p class="pl-1">或将图片拖拽到此处</p>
      </div>
      <p class="text-xs text-gray-500 mt-1">支持 PNG/JPG/GIF，单张不超过 5MB</p>
      <div v-if="uploading" class="absolute inset-0 bg-white/60 flex items-center justify-center text-sm text-gray-700 rounded-lg">上传中…</div>
    </div>

    <!-- 图片列表（卡片+悬浮操作） -->
    <div v-if="images.length > 0" class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-5">
      <div v-for="(img, idx) in images" :key="img.id" class="group relative overflow-hidden rounded-xl bg-white shadow ring-1 ring-gray-200">
        <div class="aspect-[4/3] w-full bg-gray-100">
          <img :src="img.image_path" alt="" class="h-full w-full object-cover" />
        </div>
        <div class="absolute inset-x-0 top-0 flex items-center justify-between p-2">
          <span v-if="primaryEnabled && img.is_primary" class="inline-flex items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-medium text-green-800">主图</span>
          <div class="ml-auto hidden gap-2 group-hover:flex">
            <button type="button" @click="moveUp(idx)" class="rounded bg-white/90 px-2 py-1 text-[11px] text-gray-700 shadow hover:bg-white">上移</button>
            <button type="button" @click="moveDown(idx)" class="rounded bg-white/90 px-2 py-1 text-[11px] text-gray-700 shadow hover:bg-white">下移</button>
          </div>
        </div>
        <div class="absolute inset-x-0 bottom-0 hidden group-hover:flex justify-end gap-2 p-2">
          <button v-if="primaryEnabled" type="button" @click="setPrimary(img)" :disabled="img.is_primary" class="rounded bg-blue-600/90 px-2 py-1 text-[11px] text-white shadow hover:bg-blue-700 disabled:opacity-50">设为主图</button>
          <button type="button" @click="removeImage(img)" class="rounded bg-red-600/90 px-2 py-1 text-[11px] text-white shadow hover:bg-red-700">删除</button>
        </div>
      </div>
    </div>

    <div v-else class="text-sm text-gray-500 text-center">
      <slot name="empty">暂无图片，点击上方卡片上传。</slot>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useForm } from '@inertiajs/vue3'

const props = defineProps({
  resourceType: { type: String, required: true }, // 'products' | 'variants'
  resourceId: { type: [Number, String], required: true },
  primaryEnabled: { type: Boolean, default: true },
  multiple: { type: Boolean, default: true },
})

const emit = defineEmits(['updated'])

const images = ref([])
const uploading = ref(false)
const dragging = ref(false)
// CSRF token（用于兼容 Laravel 验证）
const csrfToken = typeof document !== 'undefined'
  ? (document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '')
  : ''

const routeName = (action, extra = {}) => {
  // 目前支持 products.* 路由，未来可扩展 variants.*
  const base = `${props.resourceType}.images.`
  return route(base + action, { [props.resourceType.slice(0, -1)]: props.resourceId, ...extra })
}

const fetchImages = async () => {
  const res = await fetch(routeName('index'))
  const data = await res.json()
  images.value = data.images || []
  emit('updated', images.value)
}

// 使用 Inertia useForm 支持进度条（参考官方文档）
const uploadForm = useForm({ image: null, _token: csrfToken })

const onUpload = async (e) => {
  const files = Array.from(e.target.files || [])
  if (files.length === 0) return
  uploading.value = true
  try {
    for (const f of files) {
      uploadForm.image = f
      await new Promise((resolve, reject) => {
        uploadForm.post(routeName('store'), {
          forceFormData: true,
          preserveScroll: true,
          preserveState: true,
          onSuccess: () => resolve(true),
          onError: () => reject(new Error('upload failed')),
          onFinish: () => {
            uploadForm.reset('image')
          },
        })
      })
    }
    await fetchImages()
  } catch (err) {
    // 保守 fallback：若 Inertia 上传失败，可改回 fetch 方案
    console.error(err)
  } finally {
    uploading.value = false
    e.target.value = ''
  }
}

const onDrop = async (e) => {
  dragging.value = false
  const files = Array.from(e.dataTransfer?.files || []).filter(f => f.type.startsWith('image/'))
  if (files.length === 0) return
  uploading.value = true
  try {
    for (const f of files) {
      uploadForm.image = f
      await new Promise((resolve, reject) => {
        uploadForm.post(routeName('store'), {
          forceFormData: true,
          preserveScroll: true,
          preserveState: true,
          onSuccess: () => resolve(true),
          onError: () => reject(new Error('upload failed')),
          onFinish: () => uploadForm.reset('image'),
        })
      })
    }
    await fetchImages()
  } finally {
    uploading.value = false
  }
}

const removeImage = async (img) => {
  const res = await fetch(routeName('destroy', { image: img.id }), { method: 'DELETE', headers: { 'X-Requested-With': 'XMLHttpRequest', 'X-CSRF-TOKEN': csrfToken, 'Accept': 'application/json' }, credentials: 'same-origin' })
  if (!res.ok) return
  await fetchImages()
}

const setPrimary = async (img) => {
  const res = await fetch(routeName('primary', { image: img.id }), { method: 'POST', headers: { 'X-Requested-With': 'XMLHttpRequest', 'X-CSRF-TOKEN': csrfToken, 'Accept': 'application/json' }, credentials: 'same-origin' })
  if (!res.ok) return
  await fetchImages()
}

const moveUp = async (idx) => {
  if (idx <= 0) return
  const reordered = [...images.value]
  const t = reordered[idx - 1]
  reordered[idx - 1] = reordered[idx]
  reordered[idx] = t
  await saveSort(reordered)
}

const moveDown = async (idx) => {
  if (idx >= images.value.length - 1) return
  const reordered = [...images.value]
  const t = reordered[idx + 1]
  reordered[idx + 1] = reordered[idx]
  reordered[idx] = t
  await saveSort(reordered)
}

const saveSort = async (list) => {
  const orders = {}
  list.forEach((img, i) => (orders[img.id] = (i + 1) * 10))
  const res = await fetch(routeName('sort'), { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest', 'X-CSRF-TOKEN': csrfToken, 'Accept': 'application/json' }, body: JSON.stringify({ orders }), credentials: 'same-origin' })
  if (!res.ok) return
  await fetchImages()
}

onMounted(fetchImages)
</script>


